﻿#include "DeputyPart.h"
#include "Common/TableData/ConstantConstantCfg.h"
#include "Common/TableDataEx/DeputyCfg.h"
#include "Common/TableData/AvocationComposeCfg.h"
#include "Common/TableData/AvocationConsumereelCfg.h"
#include "Common/TableDataEx/UnionCfg.h"
#include "Common/TableDataEx/DeputyCfg.h"
#include "Character/Player.h"
#include "Common/EventDefine.h"
#include "Common/AttrMgr/AttrMgr.h"
#include "Common/TableDataEx/ItemCfg.h"
#include "Character/AchievementPart.h"
#include "Character/drop/DropMgr.h"

DeputyPart::DeputyPart()
{
	InitSubItem();
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_DEPUTY_COLLECT_SKILL_INFO, &DeputyPart::CollectSkillInfo));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_DEPUTY_MAKE_SKILL_INFO, &DeputyPart::MakeSkillInfo));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_DEPUTY_MAKE_OPERATE, &DeputyPart::Make));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_DEPUTY_RESET_MASTER_SKILL, &DeputyPart::ResetMasterSkill));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_DEPUTY_FIGHT_ATTR_INFO, &DeputyPart::FightAttrInfo));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_DEPUTY_FIGHT_UPGRADE, &DeputyPart::FightUpgrade));
	m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_DEPUTY_ACTIVE_FORMULA, &DeputyPart::ActiveFormula));

	//废弃主动升级
	//m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_DEPUTY_UPGRADE_COLLECT_SKILL, &DeputyPart::CollectSkillUpgrade));
	//m_mapMsgfunc.insert(std::make_pair(CLIENT_TO_SERVER_DEPUTY_REFINE_MAKE_SKILL, &DeputyPart::MakeSkillUpgrade));
}

void DeputyPart::InitSubItem()
{
	for (int32_t i = ECollectDeputyType_None; i < ECollectDeputyType_Limit; ++i)
	{
		SDeputySubItem sub;
		sub.byType = i;
		sub.subLvl = 1;	//采集技能默认1级
		m_collectInfo.vec.push_back(sub);
	}

	for (int32_t j = EMakeDeputyType_None; j <= EMakeDeputyType_Starsoul; ++j)
	{
		SDeputySubItem sub;
		sub.byType = j;
		sub.subLvl = 1;	//制造技能默认1级
		m_vecMake.push_back(sub);
	}

	SET_UINT32 *pLowSet = g_GetDeputyCfgMgr()->GetGuildCollegeSet(EDeputyFightMailType_Low);
	if (nullptr != pLowSet)
	{
		for (SET_UINT32::iterator iter = pLowSet->begin(); iter != pLowSet->end(); ++iter)
		{
			DeputyFightAttr attr;
			attr.mainType = EDeputyFightMailType_Low;
			attr.type = *iter;
			m_vecFightAttr.push_back(attr);
		}
	}

	SET_UINT32 *pHighSet = g_GetDeputyCfgMgr()->GetGuildCollegeSet(EDeputyFightMailType_High);
	if (nullptr != pHighSet)
	{
		for (SET_UINT32::iterator iter = pHighSet->begin(); iter != pHighSet->end(); ++iter)
		{
			DeputyFightAttr attr;
			attr.mainType = EDeputyFightMailType_High;
			attr.type = *iter;
			m_vecFightAttr.push_back(attr);
		}
	}
}

void DeputyPart::CaclCollect(SDeputySubItem &sub, const ThingCollectCfgInfo *pCollectCfg)
{
	if (nullptr == pCollectCfg)
	{
		return;
	}

	const AvocationAvocationskillCfgInfo *pCollectSkill = g_GetDeputyCfgMgr()->GetDeputyUpgradeSkillCfg(EDeputyType_Collect, pCollectCfg->type, sub.subLvl);
	if (pCollectSkill && sub.subValue >= pCollectSkill->exp)
	{
		return;
	}

	/*获得熟练度
	成功进行低于采集技能等级的副业操作获得的熟练度衰减
	成功进行符合采集技能等级的副业操作可以获得5点熟练度*/
	int32_t add_energy = 0;			//熟练度
	int32_t add_top_energy = 0;		//上古神明熟练度
	int32_t add_mid_energy = 0;		//中古神明熟练度

	int32_t interLvl = sub.subLvl - pCollectCfg->needLevel;
	if (interLvl <= 0)
	{
		/*暂定：
		5％几率获得上古神明的祝福，获得5倍采集熟练度经验;
		10％几率获得中古神明的祝福，获得2倍采集熟练度经验;
		没有获得神明的祝福则正常获得采集熟练度经验.即85％的几率正常获得采集熟练度经验.
		在3个概率中随机一个。*/
		const ConstantConstantCfgInfo *pHigherRateCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_DeputyHigherRate);
		const ConstantConstantCfgInfo *pMediumRatecCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_DeputyMediumRate);
		const ConstantConstantCfgInfo *pHigherMultipleCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_DeputyHigherMultiple);
		const ConstantConstantCfgInfo *pMediumMultipleCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_DeputyMediumMultiple);

		if (nullptr == pHigherRateCfg || nullptr == pMediumRatecCfg || nullptr == pHigherMultipleCfg || nullptr == pMediumMultipleCfg)
		{
			LogErrFmtPrint("[logic] DeputyPart::CollectFinish.....nullptr == pHigherRateCfg ");
			return;
		}

		int32_t randint = Random(100);
		if (randint <= pHigherRateCfg->constantdata)
		{
			add_top_energy = pHigherMultipleCfg->constantdata * pCollectCfg->gainValue;
			sub.subValue += add_top_energy;
		}
		else if (randint <= (pMediumRatecCfg->constantdata + pHigherRateCfg->constantdata))
		{
			add_mid_energy = pMediumMultipleCfg->constantdata * pCollectCfg->gainValue;
			sub.subValue += add_mid_energy;
		}
		else
		{
			add_energy = pCollectCfg->gainValue;
			sub.subValue += add_energy;
		}
	}
	else if (interLvl < DEPUTY_COLLECT_MAX_REDUCE_LVL)	//熟练度衰减
	{
		add_energy = (1 - interLvl * 0.2) * pCollectCfg->gainValue;
		sub.subValue += add_energy;
	}

	bool lvlup = false;
	if (pCollectSkill)
	{
		while (sub.subValue >= pCollectSkill->exp)
		{
			//pCollectSkill = g_GetDeputyCfgMgr()->GetDeputyUpgradeSkillCfg(EDeputyType_Collect, pCollectCfg->type, sub.subLvl + 1);
			const AvocationAvocationskillCfgInfo *pNextCollectSkill = g_GetDeputyCfgMgr()->GetDeputyUpgradeSkillCfg(EDeputyType_Collect, pCollectCfg->type, sub.subLvl + 1);
			if (pNextCollectSkill)
			{
				sub.subValue = sub.subValue - pCollectSkill->exp;
				sub.subLvl++;
				pCollectSkill = pNextCollectSkill;
				lvlup = true;
			}
			else
			{
				sub.subValue = pCollectSkill->exp;
				break;
			}
		}
	}

	UpdateEnergy(EDeputyType_Collect, sub.byType, sub.subValue, sub.subLvl, add_energy, add_mid_energy, add_top_energy);

	if (lvlup)
	{
		CollectLevelUpEvent collect_event;
		collect_event.type = (ECollectDeputyType)sub.byType;
		collect_event.level = sub.subLvl;
		g_GetEvent()->FireExecute(EVENT_DEPUTY_COLLECT_LEVEL_UP, m_pMaster->GetCid(), CREATURE_PLAYER, &collect_event, sizeof(CollectLevelUpEvent));
	}
}

bool DeputyPart::Init(Creature *pMaster, uint32_t partType, CharacterDBInfo* pCharacterDB)
{
	Part::Init(pMaster, partType);

	Player * pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (!pPlayer)
	{
		return false;
	}

	if (!pCharacterDB)
	{
		return false;
	}

	if (pCharacterDB->has_deputydata())
	{
		const CharacterDeputyDBData &deputy = pCharacterDB->deputydata();
		if (deputy.has_collect())
		{
			const CollectDeputyDBData &collect = deputy.collect();
			int32_t isize = collect.data_size();
			for (int32_t i = 0; i < isize; ++i)
			{
				const SingleDeputyDBData &single = collect.data(i);
				if (single.type() <= ECollectDeputyType_None || single.type() >= ECollectDeputyType_Limit)
					continue;
				SDeputySubItem &sub = m_collectInfo.vec[i+1]/*m_vecCollect[i+1]*/;
				sub.subLvl = single.skill_lvl();
				sub.subValue = single.lvl_val();
			}
			m_collectInfo.masterType = collect.master_type();
		}

		if (deputy.has_make())
		{
			const MakeDeputyDBData &make = deputy.make();
			int32_t isize = make.data_size();
			for (int32_t i = 0; i < isize; ++i)
			{
				const SingleDeputyDBData &single = make.data(i);
				if (single.type() <= EMakeDeputyType_None || single.type() > EMakeDeputyType_Starsoul)
					continue;
				SDeputySubItem &sub = m_vecMake[i+1];
				sub.subLvl = single.skill_lvl();
				sub.subValue = single.lvl_val();
				int32_t isize = single.formula_list_size();
				for (int32_t i = 0; i < isize; ++i)
				{
					sub.formulaSet.insert(single.formula_list(i));
				}
			}
		}

		int32_t isize  = pCharacterDB->deputydata().fight_size();
		for (int32_t i = 0; i < isize; ++i)
		{
			const FightDeputyDBData &data = pCharacterDB->deputydata().fight(i);
			if (data.type() <= EDeputyFightType_None || data.type() >= EDeputyFightType_Limit)
				continue;
			if (data.main_type() != EDeputyFightMailType_Low && data.main_type() != EDeputyFightMailType_High)
				continue;
			DeputyFightAttr *attr = GetDeputyFightAttr((EDeputyFightMailType)data.main_type(), (EDeputyFightType)data.type());
			if (nullptr == attr)
				continue;

			attr->mainType = data.main_type();
			attr->type = data.type();
			attr->level = data.level();
			attr->count = data.count();
			attr->attrId = data.attr_id();
			attr->attrValue = data.attr_value();
			pPlayer->SetAttrPACache(g_GetAttrMgr()->GetPlayerFightModlePAttr(enFightAttrModule_Union,attr->attrId), attr->attrValue);
		}
	}

	AchievementPart *pAchievePart = dynamic_cast<AchievementPart*>(m_pMaster->GetPart(PART_ACHIEVEMENT));
	if (nullptr == pAchievePart)	return true;

	if (0 == pCharacterDB->basedata().logouttime())
	{
		AchievementParameterInfo param;
		param.type = Update_Type_Total;
		param.parameterType = EAEventType_NormalAvocation;
		for (int32_t i = ECollectDeputyType_Herbs; i < ECollectDeputyType_Limit; ++i)
		{
			SDeputySubItem &sub = m_collectInfo.vec[i];
			switch (i)
			{
			case ECollectDeputyType_Herbs:
				param.parameter = PARAMETER_TYPE_NORMALAVOCATION_MEDICINESKILL;
				break;
			case ECollectDeputyType_Mine:
				param.parameter = PARAMETER_TYPE_NORMALAVOCATION_MINESKILL;
				break;
			case ECollectDeputyType_Fish:
				param.parameter = PARAMETER_TYPE_NORMALAVOCATION_FISHSKILL;
				break;
			case ECollectDeputyType_Peel:
				param.parameter = PARAMETER_TYPE_NORMALAVOCATION_STRIPPESKILL;
				break;
			default:
				break;
			}
			param.count = sub.subLvl;
			pAchievePart->UpdateAchievement(param);
		}

		param.parameterType = EAEventType_MakeAvocation;
		for (int32_t j = EMakeDeputyType_Forge; j <= EMakeDeputyType_Medicine; ++j)
		{
			SDeputySubItem &sub = m_vecMake[j];
			switch (j)
			{
			case EMakeDeputyType_Forge:
				param.parameter = PARAMETER_TYPE_MAKEAVOCATION_CAST;
				break;
			case EMakeDeputyType_Sew:
				param.parameter = PARAMETER_TYPE_MAKEAVOCATION_SEWING;
				break;
			case EMakeDeputyType_Smelt:
				param.parameter = PARAMETER_TYPE_MAKEAVOCATION_SMELT;
				break;
			case EMakeDeputyType_Cook:
				param.parameter = PARAMETER_TYPE_MAKEAVOCATION_COOK;
				break;
			case EMakeDeputyType_Medicine:
				param.parameter = PARAMETER_TYPE_MAKEAVOCATION_PHARMACY;
				break;
			default:
				break;
			}
			param.count = sub.subLvl;
			pAchievePart->UpdateAchievement(param);
		}
	}

	return true;
}

bool DeputyPart::UnInit()
{
	g_GetEvent()->UnSubscribeAll(this);

	m_collectInfo.clear();
	m_vecMake.clear();
	m_vecFightAttr.clear();
	return true;
}

bool DeputyPart::OnMsgHandle(uint32_t cmd, const char* data, uint32_t len)
{
	mapMsgFunc::iterator iter = m_mapMsgfunc.find(cmd);
	if (iter == m_mapMsgfunc.end())
		LogErrFmtPrint("msg dont exit in DeputyPart, cmd:%d", cmd);
	else
		(this->*m_mapMsgfunc[cmd])(data, len);

	return true;
}

bool DeputyPart::SynOnLogin()
{
	Player* pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (nullptr == pPlayer)
	{
		return false;
	}

	if (pPlayer->GetLogoutTime() <= 0 || pPlayer->GetLogoutTime() <= SecOnFreshHour())
	{
		DailyUpdate(0);
	}
	return true;
}

bool DeputyPart::SaveDB(CharacterDBInfo& characterDB)
{
	CharacterDeputyDBData *protoDeputy = characterDB.mutable_deputydata();
	if (nullptr != protoDeputy)
	{
		CollectDeputyDBData *protoCollect = protoDeputy->mutable_collect();
		if (nullptr != protoCollect)
		{
			for (int32_t i = ECollectDeputyType_None + 1; i < ECollectDeputyType_Limit; ++i)
			{
				SDeputySubItem &sub = m_collectInfo.vec[i]/*m_vecCollect[i]*/;
				SingleDeputyDBData *protoSingle = protoCollect->add_data();
				if (nullptr != protoSingle)
				{
					protoSingle->set_type(i);
					protoSingle->set_skill_lvl(sub.subLvl);
					protoSingle->set_lvl_val(sub.subValue);
				}
			}
			protoCollect->set_master_type(m_collectInfo.masterType);
		}
		MakeDeputyDBData *protoMake = protoDeputy->mutable_make();
		if (nullptr != protoMake)
		{
			for (int32_t i = EMakeDeputyType_None + 1; i <= EMakeDeputyType_Starsoul; ++i)
			{
				SDeputySubItem &sub = m_vecMake[i];
				SingleDeputyDBData *protoSingle = protoMake->add_data();
				if (nullptr != protoSingle)
				{
					protoSingle->set_type(i);
					protoSingle->set_skill_lvl(sub.subLvl);
					protoSingle->set_lvl_val(sub.subValue);
					if (sub.formulaSet.size() > 0)
					{
						for (SET_UINT32::iterator it = sub.formulaSet.begin(); it != sub.formulaSet.end(); ++it)
						{
							protoSingle->add_formula_list(*it);
						}
					}
				}
			}
		}

		for (VecDeputyFightAttr::iterator it = m_vecFightAttr.begin(); it != m_vecFightAttr.end(); ++it)
		{
			DeputyFightAttr &attr = *it;
			FightDeputyDBData *pFight = protoDeputy->add_fight();
			if (nullptr != pFight)
			{
				pFight->set_main_type(attr.mainType);
				pFight->set_type(attr.type);
				pFight->set_level(attr.level);
				pFight->set_count(attr.count);
				pFight->set_attr_id(attr.attrId);
				pFight->set_attr_value(attr.attrValue);
			}
		}
	}
	return true;
}

bool DeputyPart::DailyUpdate(uint64_t unixSec)
{
	const ConstantConstantCfgInfo *pConstCollSecCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_DeputyEveryRestEnergy);
	if (nullptr == pConstCollSecCfg)
	{
		LogErrFmtPrint("[logic] DeputyPart::DailyUpdate.....nullptr == pConstCollSecCfg, id:%d ", EArg_DeputyEveryRestEnergy);
		return false;
	}
	m_pMaster->SetAttr(C_ENERGY, pConstCollSecCfg->constantdata, true);
	return true;
}

void DeputyPart::SetCollectSkill(int32_t type)
{
	if (type <= ECollectDeputyType_None || type >= ECollectDeputyType_Limit)
	{
		return;
	}
	const ConstantConstantCfgInfo *pConstCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_DeputySkillMaxLvl);
	if (nullptr == pConstCfg)
	{
		LogErrFmtPrint("[logic] DeputyPart::SetCollectSkill...nullptr == pConstCfg..id:%d ", EArg_DeputySkillMaxLvl);
		return;
	}

	SDeputySubItem &sub = m_collectInfo.vec[type]/*m_vecCollect[type]*/;
	if (sub.subLvl >= pConstCfg->constantdata)
	{
		//LogErrFmtPrint("[logic] DeputyPart::CollectSkillUpgrade...nullptr == pConstCfg..id:%u ", EArg_DeputySkillMaxLvl);
		return;
	}
	sub.subLvl += 1;

	CollectLevelUpEvent collect_event;
	collect_event.type = (ECollectDeputyType)sub.byType;
	collect_event.level = sub.subLvl;
	g_GetEvent()->FireExecute(EVENT_DEPUTY_COLLECT_LEVEL_UP, m_pMaster->GetCid(), CREATURE_PLAYER, &collect_event, sizeof(CollectLevelUpEvent));

	const AvocationAvocationskillCfgInfo *pAvocationCfg = g_GetDeputyCfgMgr()->GetDeputyUpgradeSkillCfg(EDeputyType_Collect, type, sub.subLvl);
	if (nullptr == pAvocationCfg)
	{
		LogErrFmtPrint("[logic] DeputyPart::SetCollectSkill...nullptr == pAvocationCfg");
		return;
	}
	sub.subValue = pAvocationCfg->exp;
	UpdateEnergy(EDeputyType_Collect, type, sub.subValue, sub.subLvl);
}

void DeputyPart::AddCollectEnergy(int32_t type, int32_t value)
{
	if (type <= ECollectDeputyType_None || type >= ECollectDeputyType_Limit)
	{
		return;
	}

	SDeputySubItem &sub = m_collectInfo.vec[type];
	const AvocationAvocationskillCfgInfo *pAvocationCfg = g_GetDeputyCfgMgr()->GetDeputyUpgradeSkillCfg(EDeputyType_Collect, sub.byType, sub.subLvl);
	if (nullptr == pAvocationCfg)
	{
		return;
	}
	bool lvlup = false;
	sub.subValue += value;
	while (sub.subValue >= pAvocationCfg->exp)
	{
		const AvocationAvocationskillCfgInfo *pNextCollectSkill = g_GetDeputyCfgMgr()->GetDeputyUpgradeSkillCfg(EDeputyType_Collect, pAvocationCfg->type, sub.subLvl + 1);
		if (pNextCollectSkill)
		{
			sub.subValue = sub.subValue - pAvocationCfg->exp;
			sub.subLvl++;
			pAvocationCfg = pNextCollectSkill;
			lvlup = true;
		}
		else
		{
			sub.subValue = pAvocationCfg->exp;
			break;
		}
	}
	UpdateEnergy(EDeputyType_Collect, type, sub.subValue, sub.subLvl, value);

	if (lvlup)
	{
		CollectLevelUpEvent collect_event;
		collect_event.type = (ECollectDeputyType)sub.byType;
		collect_event.level = sub.subLvl;
		g_GetEvent()->FireExecute(EVENT_DEPUTY_COLLECT_LEVEL_UP, m_pMaster->GetCid(), CREATURE_PLAYER, &collect_event, sizeof(CollectLevelUpEvent));
	}
}

void DeputyPart::AddMakeEnergy(int32_t type, int32_t value)
{
	if (type <= EMakeDeputyType_None || type > EMakeDeputyType_Starsoul)
	{
		return;
	}

	SDeputySubItem &sub = m_vecMake[type];
	const AvocationAvocationskillCfgInfo *pAvocationCfg = g_GetDeputyCfgMgr()->GetDeputyUpgradeSkillCfg(EDeputyType_Make, sub.byType, sub.subLvl);

	if (nullptr == pAvocationCfg)
	{
		return;
	}
	bool lvlup = false;
	sub.subValue += value;
	while (sub.subValue >= pAvocationCfg->exp)
	{
		const AvocationAvocationskillCfgInfo *pNextCollectSkill = g_GetDeputyCfgMgr()->GetDeputyUpgradeSkillCfg(EDeputyType_Make, pAvocationCfg->type, sub.subLvl + 1);
		if (pNextCollectSkill)
		{
			sub.subValue = sub.subValue - pAvocationCfg->exp;
			sub.subLvl++;
			pAvocationCfg = pNextCollectSkill;
			lvlup = true;
		}
		else
		{
			sub.subValue = pAvocationCfg->exp;
			break;
		}
	}
	UpdateEnergy(EDeputyType_Make, type, sub.subValue, sub.subLvl);

	if (lvlup)
	{
		ForgeLevelUpEvent collect_event;
		collect_event.type = (EMakeDeputyType)sub.byType;
		collect_event.level = sub.subLvl;
		g_GetEvent()->FireExecute(EVENT_DEPUTY_FORGE_LEVEL_UP, m_pMaster->GetCid(), CREATURE_PLAYER, &collect_event, sizeof(CollectLevelUpEvent));
	}
}

void DeputyPart::SetMakeSkill(/*EMakeDeputyType*/int32_t type)
{
	if (type <= EMakeDeputyType_None || type > EMakeDeputyType_Starsoul)
	{
		return;
	}

	const ConstantConstantCfgInfo *pConstMaxLvlCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_LifeSkillMaxLel);
	if (nullptr == pConstMaxLvlCfg)
	{
		LogErrFmtPrint("[logic] DeputyPart::SetMakeSkill...nullptr == pConstMaxLvlCfg..id:%u ", EArg_LifeSkillMaxLel);
		return;
	}

	SDeputySubItem &sub = m_vecMake[type];
	if (sub.subLvl >= pConstMaxLvlCfg->constantdata)
	{
		return;
	}
	sub.subLvl += 1;
	UpdateEnergy(EDeputyType_Make, type, sub.subValue, sub.subLvl);

	ForgeLevelUpEvent make_event;
	make_event.type = (EMakeDeputyType)sub.byType;
	make_event.level = sub.subLvl;
	g_GetEvent()->FireExecute(EVENT_DEPUTY_FORGE_LEVEL_UP, m_pMaster->GetCid(), CREATURE_PLAYER, &make_event, sizeof(ForgeLevelUpEvent));
}

int32_t DeputyPart::GetCollectSkillLvl(ECollectDeputyType type)
{
	if (type <= ECollectDeputyType_None || type >= ECollectDeputyType_Limit)
	{
		return 0;
	}

	return m_collectInfo.vec[type].subLvl;
}

int32_t DeputyPart::GetMakeSkillLvl(EMakeDeputyType type)
{
	if (type <= EMakeDeputyType_None || type > EMakeDeputyType_Starsoul)
	{
		return 0;
	}

	return m_vecMake[type].subLvl;
}

ERetCode DeputyPart::CollectVerify(const ThingCollectCfgInfo *pCfg)
{
	SDeputySubItem &sub = m_collectInfo.vec[pCfg->type];
	if (sub.subLvl < pCfg->needLevel)	//副业等级不够=足
	{
		return RET_DEPUTY_LACK_LEVEL;
	}
	return RET_SUCCESS;
}


ERetCode DeputyPart::CollectFinish(const ThingCollectCfgInfo *pCollectCfg, LIST_ITEM &lstItem)
{
	if (nullptr == pCollectCfg)
	{
		LogErrFmtPrint("DeputyPart::CanCollectFinish...nullptr == pCollectCfg", pCollectCfg->id);
		return RET_FAIL;
	}

	Part *pPackage = m_pMaster->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		LogErrFmtPrint("DeputyPart::CanCollectFinish...nullptr == pPackage");
		return RET_FAIL;
	}

	SDeputySubItem &sub = m_collectInfo.vec[pCollectCfg->type];
	const AvocationAvocationskillCfgInfo *pCollectSkill = g_GetDeputyCfgMgr()->GetDeputyUpgradeSkillCfg(EDeputyType_Collect, pCollectCfg->type, sub.subLvl);
	if (nullptr == pCollectSkill)
	{
		LogErrFmtPrint("[logic] DeputyPart::CanCollectFinish....nullptr == pCollectSkill....DeputyType=%d,CollectType=%d,subLvl=%d) ", EDeputyType_Collect, pCollectCfg->type, sub.subLvl + 1);
		return RET_FAIL;
	}

	if (pCollectCfg->gainValue > 0)
	{
		int32_t succesRand = Random(100);
		int32_t lvlEnergy = g_GetDeputyCfgMgr()->GetEnergyByLel(sub.subLvl);
		int32_t succes = lvlEnergy * 100 / (float)pCollectCfg->gainValue;
		if (succesRand > succes)
		{
			//这里采集失败 只是没有获得采集物 但是还是要移除采集物
			return RET_DEPUTY_COLLECT_ERROR;
		}
	}

	lstItem.clear();
	if (pCollectCfg->getItemId > 0)	//采集资源
	{
		SItem item;
		item.nItemID = pCollectCfg->getItemId;
		item.nNum = Random(1, 3);
		item.byBind = (int8_t)EBindState::EBindState_no;
		lstItem.push_back(item);
	}

	for (VecThingCollectAccompanimentsCfg::const_iterator iter = pCollectCfg->vecThingCollectAccompanimentsCfg.begin(); iter != pCollectCfg->vecThingCollectAccompanimentsCfg.end(); ++iter)
	{
		const ThingCollectAccompanimentsCfgInfo &cfgInfo = *iter;
		if (cfgInfo.Id <= 0)	
			continue;

		if ((int32_t)Random(10000) <= cfgInfo.Rate)
		{
			SItem item;
			item.nItemID = cfgInfo.Id;
			item.nNum = Random(1, 3);
			item.byBind = (int8_t)EBindState::EBindState_no;
			lstItem.push_back(item);
		}
	}

	if (!pPackage->CanAddItem(lstItem))
	{
		return RET_PACKAGE_SPACE_NOT_ENOUGH;
	}

	return RET_SUCCESS;
}

void DeputyPart::CollectGain(const ThingCollectCfgInfo *pCollectCfg, LIST_ITEM &lstItem)
{
	if (nullptr == pCollectCfg)
	{
		LogErrFmtPrint("DeputyPart::CollectGain...nullptr == pCollectCfg", pCollectCfg->id);
		return;
	}

	SDeputySubItem &sub = m_collectInfo.vec[pCollectCfg->type];
	Part *pPackage = m_pMaster->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		LogErrFmtPrint("DeputyPart::CollectGain...nullptr == pPackage");
		return;
	}

	SItemSourceParam sourceParam;
	sourceParam.source = S_DEPUTY;
	pPackage->AddItem(lstItem, sourceParam);

	CollectOperateEvent operate_event;
	operate_event.type = (ECollectDeputyType)sub.byType;
	operate_event.level = pCollectCfg->needLevel;
	g_GetEvent()->FireExecute(EVENT_DEPUTY_COLLECT_OPERATE, m_pMaster->GetCid(), CREATURE_PLAYER, &operate_event, sizeof(CollectOperateEvent));

	CaclCollect(sub, pCollectCfg);
	m_pMaster->AddAttr(C_ENERGY, -pCollectCfg->needEnergy, true);
}

void DeputyPart::CollectSkillInfo(const char *data, uint32_t len)
{
	Deputy_CollectSkillInfoRsp ret;
	CollectDeputyDBData *cData = ret.mutable_data();
	for (int32_t i = ECollectDeputyType_None + 1; i < ECollectDeputyType_Limit;++i)
	{
		SDeputySubItem &sub = m_collectInfo.vec[i]/*m_vecCollect[i]*/;
		SingleDeputyDBData *protoSingle = cData->add_data();
		if (nullptr != protoSingle)
		{
			protoSingle->set_type(sub.byType);
			protoSingle->set_skill_lvl(sub.subLvl);
			protoSingle->set_lvl_val(sub.subValue);
		}
	}
	cData->set_master_type(m_collectInfo.masterType);

	m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_COLLECT_SKILL_INFO, &ret);
}

void DeputyPart::UpdateEnergy(EDeputyType type, int32_t collectType, int32_t energy, int32_t subLvl, int32_t add_energy, int32_t mid_energy, int32_t top_energy)
{
	Deputy_CollectEnergyUpdate update;
	update.set_deputy_type(type);
	update.set_collect_type(collectType);
	update.set_level(subLvl);
	update.set_energy(energy);
	update.set_add_energy(add_energy);
	update.set_add_mid_energy(mid_energy);
	update.set_add_top_energy(top_energy);
	m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_UPDATE_COLLECT_ENERGY, &update);	
}

void DeputyPart::FightAttrInfo(const char *data, uint32_t len)
{
	Deputy_FightAttrInfoReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] Deputy_FightAttrInfoReq parse failed....");
		return;
	}

	Deputy_FightAttrInfoRsp rsp;
	for (VecDeputyFightAttr::iterator it = m_vecFightAttr.begin(); it != m_vecFightAttr.end(); ++it)
	{
		DeputyFightAttr &attr = *it;
		FightDeputyDBData *pFight = rsp.add_fight();
		if (nullptr != pFight)
		{
			pFight->set_main_type(attr.mainType);
			pFight->set_type(attr.type);
			pFight->set_level(attr.level);
			pFight->set_count(attr.count);
			pFight->set_attr_id(attr.attrId);
			pFight->set_attr_value(attr.attrValue);
		}
	}
	m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_ATTR_INFO, &rsp);
}

void DeputyPart::FightUpgrade(const char *data, uint32_t len)
{
	Deputy_FightUpgradeReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] Deputy_FightUpgradeReq parse failed....");
		return;
	}

	Deputy_FightUpgradeRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	int32_t mainType = req.main_type();
	int32_t type = req.type();
	int32_t operate = req.operate();

	if (mainType != EDeputyFightMailType_Low && mainType != EDeputyFightMailType_High)
	{
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}

	if (type <= EDeputyFightType_None || type >= EDeputyFightType_Limit)
	{
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}

	if (operate != 1 && operate != 2)
	{
		LogDebugFmtPrint("[logic] FightUpgrade... operate is error....operate=%d", operate);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}

	DeputyFightAttr *attr = GetDeputyFightAttr((EDeputyFightMailType)mainType, (EDeputyFightType)type);
	if (nullptr == attr)
	{
		LogDebugFmtPrint("[logic] FightUpgrade...nullptr == attr....mainType=%d, type=%d", mainType, type);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}

	int32_t nextLel = attr->level + 1;
	const GuildCollegeCfgInfo* pCfg = g_GetDeputyCfgMgr()->GetGuildCollegeCfgInfo(mainType, type, nextLel);
	if (nullptr == pCfg)
	{
		rsp.set_retcode(RET_DEPUTY_FIGHT_UP_LEVEL_LIMIT);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}

	if (pCfg->playerLevelLimit > m_pMaster->GetAttr(C_LEVEL))
	{
		rsp.set_retcode(RET_LEVEL_LACK);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}

	LC_UnionFightUpVerifyReq verify;
	verify.set_char_id(m_pMaster->GetCid());
	verify.set_main_type(mainType);
	verify.set_type(type);
	verify.set_operate(req.operate());
	g_GetLogicService()->SendDataToCenter(EMODULE_ID_UNION, LOGIC_TO_CENTER_UNION_FIGHT_UP_VERIFY, &verify);
}

void DeputyPart::ActiveFormula(const char *data, uint32_t len)
{
	Deputy_ActiveFormulaReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] Deputy_ActiveFormulaReq parse failed....");
		return;
	}

	Deputy_ActiveFormulaRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	Part* pPart = m_pMaster->GetPart(PART_PACKAGE);
	if (nullptr == pPart)
	{
		LogErrFmtPrint("[logic] DeputyPart::ActiveFormula pPackage part is nullptr charId=%lu", m_pMaster->GetCid());
		return;
	}

	const CItemBase* pItem = pPart->GetItem(req.index());
	if (nullptr == pItem)
	{
		rsp.set_retcode(RET_PACKAGE_ITEM_NOT_EXITS);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_ACTIVE_FORMULA, &rsp);
		return;
	}
	
	const VEC_INT32 *pvecPara = g_GetItemCfgMgr()->GetItemFuncParamCfg(pItem->GetItemID());
	if (nullptr == pvecPara)
	{
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_ACTIVE_FORMULA, &rsp);
		return;
	}
	if (pvecPara->size() < 1)
	{
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_ACTIVE_FORMULA, &rsp);
		return;
	}

	uint32_t formulaId = pvecPara->at(0);
	const AvocationComposeCfgInfo *pComposeCfg = g_GetAvocationComposeCfgTable()->GetAvocationComposeCfgInfo(formulaId);
	if (nullptr == pComposeCfg)
	{
		LogErrFmtPrint("[logic] DeputyPart::ActiveFormula....nullptr == pComposeCfg  formulaId:%d ", formulaId);
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_ACTIVE_FORMULA, &rsp);
		return;
	}

	if (pComposeCfg->formula != 2 || pComposeCfg->type <= EMakeDeputyType_None || pComposeCfg->type > EMakeDeputyType_Starsoul)
	{
		rsp.set_retcode(RET_DEPUTY_CONFIG_TYPE_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_ACTIVE_FORMULA, &rsp);
		return;
	}

	SDeputySubItem &sub = m_vecMake[pComposeCfg->type];
	if (sub.subLvl < pComposeCfg->skillMinLevel)
	{
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_ACTIVE_FORMULA, &rsp);
		return;
	}

	if (sub.formulaSet.count(formulaId) > 0)
	{
		rsp.set_retcode(RET_DEPUTY_FORMULA_ALREADY_ACTIVE);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_ACTIVE_FORMULA, &rsp);
		return;
	}

	sub.formulaSet.insert(formulaId);
	rsp.set_formula_id(formulaId);
	m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_ACTIVE_FORMULA, &rsp);

	SItemSourceParam sourceParam;
	sourceParam.source = S_DEPUTY;
	pPart->RemoveItemByIndex(req.index(), 1, sourceParam);
}

void DeputyPart::FightUpgrade_VerifyReturn(CL_UnionFightUpVerifyRsp &verifyRsp)
{
	Deputy_FightUpgradeRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	if (verifyRsp.retcode() != RET_SUCCESS)
	{
		rsp.set_retcode(verifyRsp.retcode());
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}
	
	Part *pPart = m_pMaster->GetPart(PART_PACKAGE);
	if (nullptr == pPart)
	{
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}

	const GuildConstantCfgInfo *pConstCfg = g_GetUnionCfgMgr()->GetUnionInitCfgInfo();
	if (nullptr == pConstCfg)
	{
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}

	int32_t mainType = verifyRsp.main_type();					
	int32_t type = verifyRsp.type();							//精修类型
	DeputyFightAttr *attr = GetDeputyFightAttr((EDeputyFightMailType)mainType, (EDeputyFightType)type);
	if (nullptr == attr)
	{
		LogDebugFmtPrint("[logic] FightUpgrade_VerifyReturn...nullptr == attr....mainType=%d, type=%d", mainType, type);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}

	int32_t nextLel = attr->level + 1;
	const GuildCollegeCfgInfo* pCfg = g_GetDeputyCfgMgr()->GetGuildCollegeCfgInfo(mainType, type, nextLel);
	if (nullptr == pCfg)
	{
		LogErrFmtPrint("[logic] FightUpgrade_VerifyReturn.... pCfg = nullptr failed....type=%d, nextLel=%d", type, nextLel);
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}

	if (pCfg->magicHouseLevelLimit > verifyRsp.collage_level())
	{
		rsp.set_retcode(RET_DEPUTY_COLLAGE_LEVEL_LIMIT);
		m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
		return;
	}

	if (verifyRsp.operate() == 1)	//普通精修 扣除金币和公会贡献
	{
		if (m_pMaster->GetAttr(C_GOLD) < pCfg->CostMoney)
		{
			rsp.set_retcode(RET_GOLD_LACK);
			m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
			return;
		}
		if (m_pMaster->GetAttr(C_UNION_CONTRI) < pCfg->CostContribute)
		{
			rsp.set_retcode(RET_MALL_UNIONCONTRI_LACK);
			m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
			return;
		}
		m_pMaster->AddSourceAttr(C_GOLD, -pCfg->CostMoney, true, S_DEPUTY);
		//通知中心服扣除公会贡献
		LC_UnionUpdateAttrReq req;
		req.set_charid(m_pMaster->GetCid());
		req.set_unioncontri(-pCfg->CostContribute);
		req.set_source(S_DEPUTY);
		g_GetLogicService()->SendDataToCenter(EMODULE_ID_UNION, LOGIC_TO_CENTER_UNION_UPDATE_ATTR, &req);
	}
	else  //药剂精修
	{
		SItemSourceParam soureParam;
		soureParam.source = S_DEPUTY;
		if (!pPart->RemoveItem(pConstCfg->practiceMedicineId, pCfg->CostMedicamentNum, soureParam))
		{
			rsp.set_retcode(RET_PACKAGE_ITEM_NUM_LACK);
			m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);
			return;
		}
	}

	attr->count++;
	if (attr->count >= pCfg->practiceTimes)
	{
		attr->level = nextLel;
		attr->count = 0;
		attr->attrValue = pCfg->attributeGain > 0 ? pCfg->attributeGain : pCfg->attributeGainPercent;
		attr->attrId = pCfg->attributeId;
	}

	rsp.set_type(attr->type);
	rsp.set_main_type(attr->mainType);
	rsp.set_level(attr->level);
	rsp.set_count(attr->count);
	m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_FIGHT_UPGRADE, &rsp);

	int32_t totalLvl = 0;
	for (int32_t i = EDeputyFightType_None + 1; i < EDeputyFightType_Limit; ++i)
	{
		DeputyFightAttr &attr = m_vecFightAttr[i];
		totalLvl += attr.level;
	}

	UnionFightUpgrade upgrade;
	upgrade.level = attr->level;
	upgrade.totalaLvl = totalLvl;
	g_GetEvent()->FireExecute(EVENT_UNION_FIGHT_UPGRADE, m_pMaster->GetCid(), CREATURE_PLAYER, &upgrade, sizeof(UnionFightUpgrade));

	Player * pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (pPlayer)
	{
		pPlayer->SetAttrPA(g_GetAttrMgr()->GetPlayerFightModlePAttr(enFightAttrModule_Union, attr->attrId), attr->attrValue, true);
		uint64_t newContri = m_pMaster->GetAttr(C_UNION_CONTRI);
		uint64_t preContri = newContri + pCfg->CostContribute;
		uint64_t newGold = m_pMaster->GetAttr(C_GOLD);
		uint64_t preGold = newGold + pCfg->CostMoney;
		pPlayer->UnionUpgradeLog(attr->level, pCfg->CostContribute, preContri, newContri, pCfg->CostMoney, preGold, newGold);
	}
}

////////////////////////////////// 制造副业////////////////////////////////////////
void DeputyPart::MakeSkillInfo(const char *data, uint32_t len)
{
	Deputy_MakeSkillInfoRsp ret;
	for (int32_t i = EMakeDeputyType_None + 1; i <= EMakeDeputyType_Starsoul; ++i)
	{
		SDeputySubItem &sub = m_vecMake[i];
		SingleDeputyDBData *protoSingle = ret.add_data();
		if (nullptr != protoSingle)
		{
			protoSingle->set_type(sub.byType);
			protoSingle->set_skill_lvl(sub.subLvl);
			protoSingle->set_lvl_val(sub.subValue);
			if (sub.formulaSet.size() > 0)
			{
				for (SET_UINT32::iterator it = sub.formulaSet.begin(); it != sub.formulaSet.end(); ++it)
				{
					protoSingle->add_formula_list(*it);
				}
			}
		}
	}
	m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_SKILL_INFO, &ret);

}

void DeputyPart::Make(const char *data, uint32_t len)
{
	Deputy_MakeOperateReq req;
	if (!req.ParseFromArray(data, len))
	{
		LogErrFmtPrint("[logic] DeputyPart::Make...Deputy_MakeOperateReq parse failed...");
		return;
	}

	Deputy_MakeOperateRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	const AvocationComposeCfgInfo *pComposeCfg = g_GetAvocationComposeCfgTable()->GetAvocationComposeCfgInfo(req.make_id());
	if (nullptr == pComposeCfg)
	{
		LogErrFmtPrint("[logic] DeputyPart::Make....nullptr == pComposeCfg  makeId:%d ", req.make_id());
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
		return;
	}

	Part *pPackage = m_pMaster->GetPart(PART_PACKAGE);
	if (nullptr == pPackage)
	{
		LogErrFmtPrint("[logic] DeputyPart::Make nullptr == pPackage....");
		return;
	}

	Player* pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (nullptr == pPlayer)
	{
		LogErrFmtPrint("[logic] DeputyPart::Make nullptr == pPlayer....");
		rsp.set_retcode(RET_NOT_HAVE_CHARACTER);
		m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
		return;
	}

	if (!req.has_make_num())
	{
		LogErrFmtPrint("[logic] DeputyPart::Make....!req.has_make_num() false...");
		rsp.set_retcode(RET_DEPUTY_MAKE_NUM_LACK);
		m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
		return;
	}

	int32_t makeNum = req.make_num();
	int32_t makeId = req.make_id();
	if (makeNum < 1)
	{
		LogErrFmtPrint("[logic] DeputyPart::Make...makeNum < 1...makeNum:%d ", makeNum);
		rsp.set_retcode(RET_DEPUTY_MAKE_NUM_LACK);
		m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
		return;
	}

	int32_t costEnergy = pComposeCfg->needEnergy * makeNum;
	if ((int32_t)m_pMaster->GetAttr(C_ENERGY) < costEnergy)
	{
		rsp.set_retcode(RET_DEPUTY_LACK_ENERGY);
		m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
		return;
	}

	int64_t costGold = pComposeCfg->needMoney * makeNum;
	if (m_pMaster->GetAttr(C_GOLD) < costGold)
	{
		rsp.set_retcode(RET_GOLD_LACK);
		m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
		return;
	}

	SDeputySubItem &sub = m_vecMake[pComposeCfg->type];
	const AvocationAvocationskillCfgInfo *pSkillCfg = g_GetDeputyCfgMgr()->GetDeputyUpgradeSkillCfg(EDeputyType_Make, pComposeCfg->type, sub.subLvl);
	if (nullptr == pSkillCfg)
	{
		LogErrFmtPrint("[logic] DeputyPart::Make....nullptr == pSkillCfg...subType:%d, level:%d ", pComposeCfg->type, sub.subLvl);
		rsp.set_retcode(RET_CONFIG_ERROR);
		m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
		return;
	}

	VEC_INT32 vecOpenMakeList;
	string strOpen = pSkillCfg->openCreateList;
	StringSplit2Int(strOpen, ';', vecOpenMakeList);
	VEC_INT32::iterator iterOpen = std::find(vecOpenMakeList.begin(), vecOpenMakeList.end(), makeId);
	if (iterOpen == vecOpenMakeList.end())		//制造列表未开启
	{
		rsp.set_retcode(RET_DEPUTY_MAKE_LIST_NOT_OPEN);
		m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
		return;
	}

	LIST_ITEM lstRemoveItem;
	LIST_ITEM lstAddItem;
	lstRemoveItem.clear();
	lstAddItem.clear();

	if (pComposeCfg->sonType == 1)		//装备
	{
		if (makeNum != 1)	//装备只能制造一件
		{
			LogErrFmtPrint("[logic] DeputyPart::Make...pComposeCfg->sonType == 1 && makeNum != 1...makeNum:%d ", makeNum);
			rsp.set_retcode(RET_DEPUTY_MAKE_NUM_LACK);
			m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
			return;
		}

		if (!req.has_reel_id())	//制作装备的时候是需要卷轴ID
		{
			rsp.set_retcode(RET_DEPUTY_STOVE_NOT_EXIST);
			m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
			return;
		}

		int32_t reelId = req.reel_id();

		//需要的材料
		const AvocationConsumereelCfgInfo *consumereelCfg = g_GetAvocationConsumereelCfgTable()->GetAvocationConsumereelCfgInfo(reelId);
		if (nullptr == consumereelCfg)
		{
			LogErrFmtPrint("[logic] DeputyPart::Make consumereelCfg nullptr....reelId=%d", reelId);
			rsp.set_retcode(RET_CONFIG_ERROR);
			m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
			return;
		}

		SItem item;
		item.nItemID = reelId;
		item.nNum = 1;
		item.byBind = (int8_t)EBindState::EBindState_all;
		lstRemoveItem.push_back(item);

		if (pComposeCfg->consumeRandomReel_Id == reelId)	//随机卷轴	随机目标物品
		{
			int32_t totalRate = 0;
			VEC_INT32 vecItem;
			VEC_INT32 vecRate;
			VecAvocationComposeNewItemCfg::const_iterator iterRate = pComposeCfg->vecAvocationComposeNewItemCfg.begin();
			for (; iterRate != pComposeCfg->vecAvocationComposeNewItemCfg.end(); ++iterRate)
			{
				const AvocationComposeNewItemCfgInfo &info = (*iterRate);
				if (info.Id > 0)
				{
					vecItem.push_back(info.Id);
					vecRate.push_back(info.Rate);
					totalRate += info.Rate;
				}
			}

			if (vecItem.size() < 1)
			{
				LogErrFmtPrint("[logic] DeputyPart::Make....has no item to rand...makeid:%d ", makeId);
				rsp.set_retcode(RET_CONFIG_ERROR);
				m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
				return;
			}

			int32_t randNum = Random(totalRate + 1);		// 0 - totalRate
			int32_t tempRate = 0;
			int32_t tempSize = vecItem.size();
			for (int32_t i = 0; i < tempSize; ++i)
			{
				tempRate += vecRate.at(i);
				if (randNum <= tempRate)
				{
					SItem item;
					item.nItemID = vecItem.at(i);
					item.nNum = makeNum;
					item.byBind = (int8_t)EBindState::EBindState_no;
					lstAddItem.push_back(item);
					break;
				}
			}
		}
		else
		{
			if (pComposeCfg->vecAvocationComposeConsumeReelCfg.size() != pComposeCfg->vecAvocationComposeNewItemCfg.size())
			{
				LogErrFmtPrint("[logic] DeputyPart::Make....equip reel size not equal to compose rand item size ....makeid:%d ", makeId);
				rsp.set_retcode(RET_CONFIG_ERROR);
				m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
				return;
			}
			int32_t tempSize = pComposeCfg->vecAvocationComposeConsumeReelCfg.size();
			for (int32_t i = 0; i < tempSize; ++i)
			{
				const AvocationComposeConsumeReelCfgInfo &info = pComposeCfg->vecAvocationComposeConsumeReelCfg.at(i);
				if (reelId == info.Id)
				{
					const AvocationComposeNewItemCfgInfo &infoA = pComposeCfg->vecAvocationComposeNewItemCfg.at(i);
					SItem item;
					item.nItemID = infoA.Id;
					item.nNum = makeNum;
					item.byBind = (int8_t)EBindState::EBindState_no;
					lstAddItem.push_back(item);
					break;
				}
			}
			const AvocationConsumereelCfgInfo *pConsumereelCfg = g_GetAvocationConsumereelCfgTable()->GetAvocationConsumereelCfgInfo(reelId);
			if (nullptr != pConsumereelCfg)
			{
				VecAvocationConsumereelNeedMaterialCfg::const_iterator iter = pConsumereelCfg->vecAvocationConsumereelNeedMaterialCfg.begin();
				for (; iter != pConsumereelCfg->vecAvocationConsumereelNeedMaterialCfg.end(); ++iter)
				{
					const AvocationConsumereelNeedMaterialCfgInfo &info = *iter;
					if (info.Id > 0 && info.Num > 0)
					{
						SItem item;
						item.nItemID = info.Id;
						item.nNum = info.Num * makeNum;
						item.byBind = (int8_t)EBindState::EBindState_all;
						lstRemoveItem.push_back(item);
					}
				}
				if (req.add())
				{
					SItem item;
					item.nItemID = pConsumereelCfg->addItemId;
					item.nNum = pConsumereelCfg->needNum;
					item.byBind = (int8_t)EBindState::EBindState_all;
					lstRemoveItem.push_back(item);
				}
			}
		}
	}
	else
	{
		VecAvocationComposeNewItemCfg::const_iterator iterNew = pComposeCfg->vecAvocationComposeNewItemCfg.begin();
		for (; iterNew != pComposeCfg->vecAvocationComposeNewItemCfg.end(); ++iterNew)
		{
			const AvocationComposeNewItemCfgInfo &info = (*iterNew);
			if (info.Id > 0)
			{
				SItem item;
				item.nItemID = info.Id;
				item.nNum = makeNum;
				item.byBind = (int8_t)EBindState::EBindState_no;
				lstAddItem.push_back(item);
				break;
			}
		}

		//需要的材料
		VecAvocationComposeNeedMaterialCfg::const_iterator iterNeed = pComposeCfg->vecAvocationComposeNeedMaterialCfg.begin();
		for (; iterNeed != pComposeCfg->vecAvocationComposeNeedMaterialCfg.end(); ++iterNeed)
		{
			const AvocationComposeNeedMaterialCfgInfo &info = (*iterNeed);
			if (info.Id > 0 && info.Num > 0)
			{
				SItem item;
				item.nItemID = info.Id;
				item.nNum = info.Num * makeNum;
				item.byBind = (int8_t)EBindState::EBindState_all;
				lstRemoveItem.push_back(item);
			}
		}
	}

	if (lstAddItem.size() <= 0)
	{
		LogErrFmtPrint("[logic] DeputyPart::Make, can not find compose destination item.... makeid:%u ", makeId);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
		return;
	}

	if (lstAddItem.size() != 1)
	{
		LogErrFmtPrint("[logic] DeputyPart::Make, item lstAddItem.size() != 1...makeId:%d, ", makeId);
		rsp.set_retcode(RET_FAIL);
		m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
		return;
	}

	if (!pPackage->HasItem(lstRemoveItem))
	{
		rsp.set_retcode(RET_DEPUTY_LACK_RES);
		m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
		return;
	}

	LIST_ITEM::iterator iterItem = lstAddItem.begin();
	SItem &addItem = (*iterItem);

	if (pComposeCfg->sonType == 1)	//装备
	{
		const EquipEquipCfgInfo *pEquipCfg = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(addItem.nItemID);
		if (nullptr == pEquipCfg)
		{
			LogErrFmtPrint("[logic] DeputyPart::Make...equip add_itemId <= 0...makeId:%d, add_itemId=%u", makeId, addItem.nItemID);
			rsp.set_retcode(RET_CONFIG_ERROR);
			m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
			return;
		}

		SItemCond itemCond;
		g_GetDropMgr()->GetItemCond(dynamic_cast<Player*>(m_pMaster), itemCond);
		if (req.add())
			itemCond.inittype = EItemInitAttrType_Duputy;
		SItemSourceParam souceParam;
		souceParam.source = S_DEPUTY;
		if (!pPackage->AddItemByMake(addItem.nItemID, pPlayer->GetName().c_str(), itemCond, souceParam, (int8_t)EBindState_no))
		{
			rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
			m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
			return;
		}

		ForgeEquipEvent forgeEvent;
		forgeEvent.type = (EMakeDeputyType)sub.byType;
		forgeEvent.itemID = addItem.nItemID;
		forgeEvent.count = addItem.nNum;
		forgeEvent.level = pEquipCfg->wearLevel;
		forgeEvent.quality = pEquipCfg->quality;
		g_GetEvent()->FireExecute(EVENT_DEPUTY_FORGE_EQUIP, m_pMaster->GetCid(), CREATURE_PLAYER, &forgeEvent, sizeof(ForgeEquipEvent));
	}
	else if (pComposeCfg->sonType == 2)	//道具
	{
		const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(addItem.nItemID);
		if (nullptr != pItemCfg)
		{
			SItemSourceParam souceParam;
			souceParam.source = S_DEPUTY;
			if (!pPackage->AddItem(lstAddItem, souceParam))
			{
				rsp.set_retcode(RET_PACKAGE_SPACE_NOT_ENOUGH);
				m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);
				return;
			}

			MakeOperateEvent operate_event;
			operate_event.type = (EMakeDeputyType)sub.byType;
			operate_event.itemID = addItem.nItemID;
			operate_event.itemNum = addItem.nNum;
			operate_event.level = pItemCfg->itemLevel;
			operate_event.composeId = pComposeCfg->id;
			g_GetEvent()->FireExecute(EVENT_DEPUTY_MAKE_OPERATE, m_pMaster->GetCid(), CREATURE_PLAYER, &operate_event, sizeof(MakeOperateEvent));
		}
		else
		{
			LogErrFmtPrint("[logic] DeputyPart::Make...equip pItemCfg = nullptr add_itemId=%u", addItem.nItemID);
		}
	}

	m_pMaster->AddSourceAttr(C_GOLD, -costGold, true, S_DEPUTY);
	m_pMaster->AddAttr(C_ENERGY, -costEnergy, true);
	SItemSourceParam souceParam;
	souceParam.source = S_DEPUTY;
	pPackage->RemoveItem(lstRemoveItem, souceParam);
	rsp.set_retcode(RET_SUCCESS);
	rsp.set_make_id(req.make_id());
	rsp.set_item_id(addItem.nItemID);
	m_pMaster->SendDataToClientEx(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_MAKE_OPERATE, &rsp);

	//增加经验
	uint32_t addExp = 0;
	int32_t interLvl = sub.subLvl - pComposeCfg->skillMinLevel;
	if (interLvl <= 0)
		addExp = pComposeCfg->gainValue;
	else if (interLvl < DEPUTY_COLLECT_MAX_REDUCE_LVL)	//熟练度衰减
		addExp = (1 - interLvl * 0.2) * pComposeCfg->gainValue;
	if (addExp <= 0)	return;

	bool lvlup = false;
	sub.subValue = sub.subValue + addExp * makeNum;
	while (sub.subValue >= pSkillCfg->exp)
	{
		const AvocationAvocationskillCfgInfo *pNextSkillCfg = g_GetDeputyCfgMgr()->GetDeputyUpgradeSkillCfg(EDeputyType_Make, pSkillCfg->type, sub.subLvl + 1);
		if (pNextSkillCfg)
		{
			sub.subValue = sub.subValue - pSkillCfg->exp;
			sub.subLvl++;
			pSkillCfg = pNextSkillCfg;
			lvlup = true;
		}
		else
		{
			sub.subValue = pSkillCfg->exp;
			break;
		}
	}
	UpdateEnergy(EDeputyType_Make, sub.byType, sub.subValue, sub.subLvl);

	if (lvlup)
	{
		ForgeLevelUpEvent collect_event;
		collect_event.type = (EMakeDeputyType)sub.byType;
		collect_event.level = sub.subLvl;
		g_GetEvent()->FireExecute(EVENT_DEPUTY_FORGE_LEVEL_UP, m_pMaster->GetCid(), CREATURE_PLAYER, &collect_event, sizeof(CollectLevelUpEvent));
	}
}

void DeputyPart::ResetMasterSkill(const char *data, uint32_t len)
{
	const ConstantConstantCfgInfo *pResetCostCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_DeputyResetSkill);
	if (nullptr == pResetCostCfg)
	{
		LogErrFmtPrint("[logic] DeputyPart::ResetMasterSkill, pResetCostCfg = nullptr......id=%d, ", EArg_DeputyResetSkill);
		return;
	}

	const ConstantConstantCfgInfo *pMaxLelCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_DeputySkillMaxLel);
	if (nullptr == pMaxLelCfg)
	{
		LogErrFmtPrint("[logic] DeputyPart::ResetMasterSkill, pMaxLelCfg = nullptr......id=%d, ", EArg_DeputySkillMaxLel);
		return;
	}

	Deputy_ResetMasterSkillRsp rsp;
	rsp.set_retcode(RET_SUCCESS);

	if ((int32_t)m_pMaster->GetAttr(C_DIAMOND) < pResetCostCfg->constantdata)
	{
		rsp.set_retcode(RET_DIAMOND_LACK);
	}
	else if (m_collectInfo.masterType <= ECollectDeputyType_None || m_collectInfo.masterType >= ECollectDeputyType_Limit)
	{
		rsp.set_retcode(RET_DEPUTY_LACK_MASTER_SKILL);
	}
	else
	{
		m_collectInfo.vec[m_collectInfo.masterType].subLvl = pMaxLelCfg->constantdata;
		m_collectInfo.vec[m_collectInfo.masterType].subValue = 0;
		UpdateEnergy(EDeputyType_Collect, m_collectInfo.masterType, m_collectInfo.vec[m_collectInfo.masterType].subValue, m_collectInfo.vec[m_collectInfo.masterType].subLvl);
		m_collectInfo.masterType = 0;
		m_pMaster->AddSourceAttr(C_DIAMOND, -pResetCostCfg->constantdata, true, S_DEPUTY);
	}
	m_pMaster->SendDataToClient(EMODULE_ID_DEPUTY, SERVER_TO_CLIENT_DEPUTY_RESET_MASTER_SKILL, &rsp);
}

DeputyFightAttr* DeputyPart::GetDeputyFightAttr(EDeputyFightMailType mainType, EDeputyFightType type)
{
	for (VecDeputyFightAttr::iterator it = m_vecFightAttr.begin(); it != m_vecFightAttr.end(); ++it)
	{
		DeputyFightAttr &attr = *it;
		if (attr.mainType == mainType && attr.type == type)
		{
			return &attr;
		}
	}
	return nullptr;
}

uint64_t DeputyPart::SecOnFreshHour(uint32_t _hour)
{
	Date date;
	Time now = Time::Now();
	now.LocalDate(&date);

	if ((uint32_t)date.hour < _hour)
	{
		return  now.UnixSec() + 3600 * _hour - (date.hour * 3600 + date.min * 60 + date.sec) - 86400;
	}
	else
	{
		return now.UnixSec() - (date.hour * 3600 + date.min * 60 + date.sec - 3600 * _hour);
	}
}
